home *** CD-ROM | disk | FTP | other *** search
- /*
- * aoi_hist.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
- /*
- * AOI_HIST(ogram).C
- *
- * routines to evaluate AOI histogram and related quantities
- *
- */
- #include "xah.h"
-
- #define NBIN_LIM 50
- #define N_BINS 51
- #define BIN_WIDTH 5
-
- #define MAX_AREA 125 /* refers to special appl */
- #define MIN_AREA 0
-
-
- #undef HIST_DEBUG
-
- /*
- * determine mean area
- */
- double
- eval_mean (int nd, unsigned int *area)
- {
- int i;
- double mean = 0.0;
-
- for (i = 0; i < nd; i++) {
- mean += (double) (*(area + i));
- }
- return (mean / (double) nd);
- }
-
-
- /*
- * determine standard deviation of input data set
- */
- double
- eval_sdev (double mean, int nd, unsigned int *area)
- {
- int i;
- double dai, var = 0.0;
-
- for (i = 0; i < nd; i++) {
- dai = (double) (*(area + i)) - mean;
- var += (dai * dai);
- }
- return (sqrt (var /= (double) (nd - 1)));
- }
-
-
- /*
- * determine skewness of input data set
- */
- double
- eval_skew (double mean, double sdev, int nd, unsigned int *area)
- {
- int i;
- double ai, dai, sk;
-
- sk = 0.0;
- for (i = 0; i < nd; i++) {
- ai = (double) (*(area + i));
- dai = (ai - mean) / sdev;
- sk += (dai * dai * dai);
- }
- return ((sk /= (double) nd));
- }
-
-
-
- /*
- * construct histogram of input data
- */
- void
- construct_hist (int n, float *data, float *hist, double bw, double base)
- {
- int i, ib;
-
- for (i = 0; i < n; i++) {
- if (*(data + i) != 0) {
- ib = 0;
- while (*(data + i) >= base + ib * bw)
- ib++;
- *(hist + ib - 1) += 1;
- }
- }
- }
-
-
-
- /*
- * construct histogram of sorted(!) input data
- */
- void
- construct_shist (int n, float *data, float *hist, double bw, double base)
- {
- int i, ib;
-
-
- ib = 0;
- for (i = 0; i < n; i++) {
- if (*(data + i) != 0) {
- while (*(data + i) >= base + ib * bw)
- ib++;
- *(hist + ib - 1) += 1;
- }
- }
- }
-
-
-
-
- /*
- * determine mean of area histogram in form of centroid:
- * (ref: F. Family & P. Meakin, Phys. Rev. A40, 3836-3854 (1989))
- */
- double
- find_hist_mean (int nb, float *hist, double bw)
- {
- int ib;
- double ssum, sssum, hi;
- double mean;
-
- ssum = sssum = 0.0;
- for (ib = 0; ib < nb; ib++) {
- hi = (double) (*(hist + ib));
- ssum += ib * hi;
- sssum += ib * ib * hi;
- }
- if ((-1.0e-10 < ssum) && (ssum < 1.0e-10))
- mean = -1.0; /* error */
- else
- mean = (sssum / ssum) * bw;
-
- return (mean);
- }
-
- /*
- * prepare to evaluate histogram
- */
- struct Histo *
- eval_hist (int BIN_METHOD, float *data, int nd, int SRT)
- {
- #ifdef HIST_DEBUG
- int ib;
- int id;
- #endif
- int nb;
- double bw, base, range;
- struct Histo *h;
-
- switch (BIN_METHOD) {
- case DEFAULT:
- nb = nd + 1;
- base = *(data + 0);
- range = *(data + nd - 1) - *(data + 0);
- if ((bw = range / (double) nb) < 1.0) { /* for area data */
- bw = 1.0;
- nb = (int) range;
- }
- break;
- case FIX_BINWD:
- bw = (double) BIN_WIDTH;
- base = *(data + 0);
- range = *(data + nd - 1) - *(data + 0);
- while ((nb = (int) (range / (int) bw)) > NBIN_LIM)
- bw++;
- break;
- case FIX_RANGE:
- nb = N_BINS;
- base = (double) MIN_AREA;
- range = (double) MAX_AREA - base;
- if (MAX_AREA < *(data + nd - 1)) {
- printf ("...WARNING: ");
- printf ("max area exceeds currently set upper limit!\n");
- }
- bw = range / (double) nb;
- break;
- case FIX_INTERVAL:
- nb = N_BINS;
- base = 0.0;
- range = 2.5;
- if (MAX_AREA < *(data + nd - 1)) {
- printf ("...WARNING: ");
- printf ("max area exceeds currently set upper limit!\n");
- }
- bw = range / (double) (nb - 1);
- break;
- default:
- printf ("\n...unknown binning method\n");
- return ((struct Histo *) NULL);
- break;
- }
-
- if ((h = (struct Histo *) calloc (1, sizeof (struct Histo))) == NULL)
- fail_alloc ("h", 1);
-
- if ((h->ph = (float *) calloc (nb, sizeof (float))) == NULL)
- fail_alloc ("h->ph", 1);
-
- #ifdef HIST_DEBUG
- printf ("...evaluate histogram: nb = %d, bw = %f\n", nb, bw);
- printf ("...input data\n");
- for (id = 0; id < nd; id++) {
- printf (" %6.2f", *(data + id));
- if ((id + 1) % 8 == 0)
- printf ("\n");
- }
- printf ("\n");
- #endif
-
- if (SRT == 1) { /* inp data sorted */
- construct_shist (nd, data, h->ph, bw, base);
-
- h->amin = *(data + 0); /* min, max inp vals */
- h->amax = *(data + nd - 1);
- }
- else {
- construct_hist (nd, data, h->ph, bw, base);
-
- h->amin = (float) -1.0; /* min, max inp vals */
- h->amax = (float) -1.0;
- }
-
-
-
- #ifdef HIST_DEBUG
- printf ("...histogram\n");
- for (ib = 0; ib < nb; ib++) {
- printf (" %4.1f ", h->ph[ib]);
- if ((ib + 1) % 10 == 0)
- printf ("\n");
- }
- printf ("\n");
- #endif
-
-
- h->nh = nd;
- h->phd = &data[0];
- h->mean = -1.0;
- h->sdev = -1.0;
- h->skew = -1.0;
-
- h->meth = BIN_METHOD;
- h->nb = nb;
- h->bw = (float) bw;
- h->hmean = find_hist_mean (nb, h->ph, bw);
-
- return (h);
- }
-